/*-----------------------------------------------------------------------*/
/* Low level disk I/O module SKELETON for FatFs     (C)ChaN, 2019        */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be        */
/* attached to the FatFs via a glue function rather than modifying it.   */
/* This is an example of glue functions to attach various exsisting      */
/* storage control modules to the FatFs module with a defined API.       */
/*-----------------------------------------------------------------------*/

#include "ff.h"		/* Obtains integer types */
#include "diskio.h" /* Declarations of disk functions */
#include "devManager.h"
#include "system.h"
extern w25qxx_t *w25qxx;
extern spi_t *spi;
/* Definitions of physical drive number for each drive */
// #define DEV_RAM		0	/* Example: Map Ramdisk to physical drive 0 */
// #define DEV_MMC		1	/* Example: Map MMC/SD card to physical drive 1 */
// #define DEV_USB		2	/* Example: Map USB MSD to physical drive 2 */
#define SPI_FLASH 0 // 本次操作的w25qxx设备，0就是w25qxx的设备编号
#define SD_CARD 1
#define W25Q64 0xEF4017 //

/*-----------------------------------------------------------------------*/
/* Get Drive Status                                                      */
/*-----------------------------------------------------------------------*/
#if !DEBUG
DSTATUS disk_status(
	BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
	// return RES_OK;

	DSTATUS status = STA_NOINIT;
	u8 MID;
	u16 DID;
	u32 FlashID = 0x00000000;
	switch (pdrv)
	{

	case SPI_FLASH:
		/* SPI Flash状态检测：读取SPI Flash 设备ID */
		
		
		//SPI_FLASH_ReadID(&MID, &DID);
		w25qxx->PspiFlashReadId(&MID, &DID);
	
		FlashID |= MID;
		FlashID <<= 16;
		FlashID |= DID;
		if (sFLASH_ID == FlashID)
		{
			/* 设备ID读取结果正确 */
			status &= ~STA_NOINIT;
		}
		else
		{
			/* 设备ID读取结果错误 */
			printf("read flashId err\r\n");
			status = STA_NOINIT;
		}
		break;
	case SD_CARD: /* SD CARD */
		break;
	default:
		status = STA_NOINIT;
	}
	return status;
}

#endif

/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */
/*-----------------------------------------------------------------------*/

DSTATUS disk_initialize(
	BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
	uint16_t i;
	DSTATUS status = STA_NOINIT;
	switch (pdrv)
	{
	case SPI_FLASH: /* SPI Flash */
		/* 初始化SPI Flash */
		//SPI_FLASH_Init();
		spi->PspiFlashInit();
		/* 延时一小段时间 */
		i = 500;
		while (--i)
			;
		/* 唤醒SPI Flash */
		/* 获取SPI Flash芯片状态 */
		status = disk_status(SPI_FLASH);
		break;
	case SD_CARD: /* SD CARD */
		break;
	default:
		status = STA_NOINIT;
	}

	return status;
}

/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
/*-----------------------------------------------------------------------*/

DRESULT disk_read(
	BYTE pdrv,	  /* Physical drive nmuber to identify the drive */
	BYTE *buff,	  /* Data buffer to store read data */
	LBA_t sector, /* Start sector in LBA */
	UINT count	  /* Number of sectors to read */
)
{
	DRESULT status = RES_PARERR;
	switch (pdrv)
	{
	case SPI_FLASH:
		/* 扇区偏移2MB，外部Flash文件系统空间放在SPI Flash后面6MB空间 */
		sector += 512;
		//SPI_FLASH_BufferRead(buff, sector << 12, count << 12);
		w25qxx->PspiFlashBufferRead(buff, sector << 12, count << 12);
		status = RES_OK;
		break;

	case SD_CARD: /* SD CARD */
		break;

	default:
		status = RES_PARERR;
	}
	return status;
}

/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */
/*-----------------------------------------------------------------------*/

#if FF_FS_READONLY == 0

DRESULT disk_write(
	BYTE pdrv,		  /* Physical drive nmuber to identify the drive */
	const BYTE *buff, /* Data to be written */
	LBA_t sector,	  /* Start sector in LBA */
	UINT count		  /* Number of sectors to write */
)
{
	uint32_t write_addr;
	DRESULT status = RES_PARERR;
	if (!count)
	{
		return RES_PARERR; /* Check parameter */
	}

	switch (pdrv)
	{

	case SPI_FLASH:
		/* 扇区偏移2MB，外部Flash文件系统空间放在SPI Flash后面6MB空间 */
		sector += 512;
		write_addr = sector << 12;
		//SPI_FLASH_SectorErase(write_addr);
		w25qxx->PspiFlashSectorErase(write_addr);
		//SPI_FLASH_BufferWrite((u8 *)buff, write_addr, count << 12);
		w25qxx->PspiFlashBufferWrite((u8 *)buff, write_addr, count << 12);
		status = RES_OK;
		break;
	case SD_CARD: /* SD CARD */
		break;
	default:
		status = RES_PARERR;
	}
	return status;
}

#endif

/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */
/*-----------------------------------------------------------------------*/

DRESULT disk_ioctl(
	BYTE pdrv, /* Physical drive nmuber (0..) */
	BYTE cmd,  /* Control code */
	void *buff /* Buffer to send/receive control data */
)
{

	DRESULT status = RES_PARERR;
	switch (pdrv)
	{

	case SPI_FLASH:
		switch (cmd)
		{
		/* 扇区数量：1536*4096/1024/1024=6(MB) */
		case GET_SECTOR_COUNT:
			*(DWORD *)buff = 1536;
			break;
		/* 扇区大小  */
		case GET_SECTOR_SIZE:
			*(WORD *)buff = 4096;
			break;
		/* 同时擦除扇区个数 */
		case GET_BLOCK_SIZE:
			*(DWORD *)buff = 1;
			break;
		}
		status = RES_OK;
		break;
	case SD_CARD: /* SD CARD */
		break;

	default:
		status = RES_PARERR;
	}
	return status;
}

__weak DWORD get_fattime(void)
{
	/* 返回当前时间戳 */
    return    ((DWORD)(2015 - 1980) << 25)  /* Year 2015 */
            | ((DWORD)1 << 21)        /* Month 1 */
            | ((DWORD)1 << 16)        /* Mday 1 */
            | ((DWORD)0 << 11)        /* Hour 0 */
            | ((DWORD)0 << 5)         /* Min 0 */
            | ((DWORD)0 >> 1);        /* Sec 0 */
}
